home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / program / 245 / gfagrphc.doc < prev    next >
Text File  |  1988-02-07  |  60KB  |  2,304 lines

  1. Figures and programs included in this Sample Chapter:
  2.  
  3. Figures:
  4.  
  5. Figure 3-1. Organization of Screen Memory for Monochrome Display.
  6. Figure 3-2 Organization of Color Screen Memory
  7. Figure 3-3. Cartesian Coordinate System
  8. Figure 3-4 Polar Coordinate System
  9. Figure 3-5. Raster Coordinate System
  10. Figure 3-6. Normalized Device Coordinate (NDC) System
  11. Figure 3-7. The Mandelbrot Primitive
  12. Figure 3-8. Mandelbrot Figure
  13. Figure 3-9. ANother Segment of the Mandelbrot Boundary.
  14.  
  15.  
  16.  
  17.  
  18.  
  19. Programs:
  20.  
  21. Program 3-1. LINEDRAW.PRG
  22. Program 3-2  STRING.BAS
  23. Program 3-3. KALEIDO.BAS
  24. Program 3-4. DRAGON.BAS
  25. Program 3-5. MANDELBROT.BAS
  26. Program 3-6. NEOWRITE.BAS
  27. Program 3-7. NEOLOAD.BAS
  28.  
  29.  
  30.  
  31. Chapter 3
  32.  
  33. ST Graphics
  34.  
  35. During the late 1950s and early 1960s, the Massachusetts Institute 
  36. of  Technoloy (MIT) was the center of the computer world, an 
  37. academic community actively involved in the research and 
  38. construction of supercomputer systems.
  39.      In 1963, Ivan Sutherland, a young graduate student working on 
  40. his doctoral dissertation at MIT, could often be seen working far 
  41. into the night at the terminal of a giant mainframe computer.  He 
  42. wasn't alone in his labors. Other students doing research on 
  43. computers had to use the late-night hours, when the mainframes 
  44. weren't being used for other purposes, for exploring the limits of 
  45. this fledgling science of computers; the technology  for 
  46. microcomputers  had not even been developed.
  47.     Sutherland wrote and rewrote his lines of code.  After much 
  48. revision, he was finally successful.  The monitor display cleared, 
  49. and a green line appeared:  The first computer graphic, a straight 
  50. line, had been produced by the giant mainframe.  Not much by 
  51. today's standards, but this occasion marked the beginning of a 
  52. whole new art form --computer graphics.
  53.      This single straight line evolved into the Sketchpad line-
  54. drawing  program.  Sutherland's early drawing program allowed the 
  55. user to point at the screen with a light pen to sketch objects. 
  56. This simple system was the predecessor of today's complex 
  57. computer-assisted drawing (CAD) programs.
  58.      A lot had to happen to computers, however, before 
  59. sophisticated computer graphics could become a reality. For a 
  60. while computers remained the expensive tools of government and 
  61. universities. In 1965, IBM introduced the first mass-produced 
  62. cathode ray tube (CRT), but the price was more than $100,000 for 
  63. the CRT only.  This price tag made entry into computer graphics 
  64. practically impossible for all but a few specialized users. In 
  65. 1968, Tektronics introduced the storage-tube CRT, which displayed 
  66. a drawing by retaining the image until the user replaced it. This 
  67. type of display eliminated the need for costly memory and hardware 
  68. to store and display the image, but the selling price of $15,000 
  69. still placed the CRT far beyond the means of most users.
  70.    It wasn't until the late 1970s and early 1980s that the 
  71. microcomputer industry exploded, and computer wars brought the 
  72. price and power of the personal computer within the reach of the 
  73. middle-income person.
  74.      Soon, powerful graphics programs such as DEGAS and NEOchrome 
  75. had introduced many people to this new art form, and some even 
  76. discovered hidden talents. And now that computer art has become 
  77. accessible to so many people, those people want to make the best 
  78. possible use of its potential.
  79.      In this chapter, we'll take you beyond DEGAS and NEOchrome, 
  80. showing you how to develop and use the powerful graphics routines 
  81. built into the ST. Previously, exploitation of these features was 
  82. rather difficult. Most programmers resorted to C or assembly 
  83. language programming when sophisticated graphics were required. 
  84. GFA BASIC delivers the power to fully utilize the graphics 
  85. potential of your ST. Stunning graphics are easily obtained using 
  86. the GFA BASIC interpreter, while the GFA BASIC compiler allows you 
  87. to develop arcade-quality games in BASIC, then execute the 
  88. programs from the GEM Desktop with your program running at speeds 
  89. rivaling those of assembly language.
  90.  
  91. Computer Graphics
  92.  
  93.      Computer graphics is a generic term which refers to any image 
  94. created with a computer. This covers a wide range, from a simple 
  95. line on a monitor, to intricate pictures developed with drawing 
  96. programs, and more. Some computer scientists, for instance, are 
  97. using computers to control lasers which produce holographic 
  98. images. Perhaps the scene from Star Wars where C3PO and Chew-baka 
  99. are playing a chesslike game with holographic images isn't even 
  100. that far-fetched.
  101.      The motion picture industry, in recent years, has used 
  102. computer graphics extensively. The transformation of the Genesis 
  103. planet in Star Trek II, The Wrath of Khan, was an effect produced 
  104. with fractal graphics --one of the most fascinating areas of 
  105. computer graphics (and one which we'll explore later in this 
  106. chapter). Disney Studios merged real action with computer-
  107. generated graphics in the movie TRON. The Last Starfighter has 25 
  108. minutes of spectacular computer imagery, with each frame requiring 
  109. dozens of algorithms and hundreds of intricate designs. In fact, 
  110. such movies have contributed to the birth of a new industry 
  111. devoted to enhancing computer-generated graphics technology, with 
  112. one of the leaders in this new industry being Lucasfilm, a pioneer 
  113. in special effects since the Star Wars trilogy.
  114.      Although holographic imaging and Hollywood-type special 
  115. effects are beyond the scope of this book, it will show you a 
  116. fascinating world open to those who know the power of the ST.
  117.  
  118.  
  119. Graphics Capabilities
  120.  
  121. Good graphics require a minimum of a high-resolution display and a 
  122. large number of colors to work with. Some rumors are beginning to 
  123. circulate about computers for homes and businesses with monitors 
  124. capable of displaying up to one million --1000  X  1000 --pixels. 
  125. Currently only dedicated graphics workstations, such as the Sun or 
  126. the Cray II, offer such capabilities, and both of these are priced 
  127. far beyond the home enthusiast's budget.  Although the ST doesn't 
  128. have the capabilities of a dedicated graphics workstation, it is 
  129. capable of displaying up to 256,000 pixels, for a fraction of the 
  130. cost. Plus, the palette of 512 colors makes it ideal for producing 
  131. colorful, exciting displays.
  132.    In order to program graphics on the ST, it's necessary to 
  133. understand a little about the way the screen is displayed. On the 
  134. monochrome screen, each pixel (picture element) is represented by 
  135. a single bit of memory.  Each bit will be either a 0 or a 1, 
  136. indicating whether each pixel is off or on, respectively. Screen 
  137. memory is organized so that the first byte represents the 8 
  138. pixels, or dots, at the top left corner of the screen. Each 
  139. succeeding byte represents the next 8 pixels in succession. Each 
  140. ⇧screen line consists of 640 pixels, so the first 80 bytes (80 
  141. times 8) represent the top row of the screen. Since there are 400 
  142. lines of pixels vertically on the screen, a total of 256,000 bits 
  143. are used to represent the monochrome screen. This means that 
  144. 32,000 bytes of screen memory are used to store the display.
  145.  
  146. Binary Decimal
  147.  00    0
  148.  01    1
  149.  10    2
  150.  11    3
  151.  
  152. Figure 3-1 Organization of Screen Memory for Monochrome Display.
  153.  
  154.     Color  screen  memory is organized in much  the  same  way  as 
  155. monochrome screen memory, but instead of single bits representing 
  156. single pixels, groups of bits are used to represent each pixel. In 
  157. medium resolution, a pixel may be one of four colors. Two bits are 
  158. used to create the four possible colors:
  159.    The first byte of screen memory represents the first four 
  160. pixels at the upper left corner of the screen. The two high-order 
  161. bits specify the color in the first pixel, the next two bits 
  162. represent the color in the second pixel, and so on. There are 640 
  163. pixels per row; each row requires 160 bytes of memory. Since there 
  164. are only 200 vertical rows of pixels, only 32,000 bytes of memory 
  165. are necessary to store a screen.
  166.    In low resolution, a pixel can be one of 16 colors, so four 
  167. bits are required to represent a single pixel.
  168.  
  169. 0000 = 0        1000 = 8
  170. 0001 = 1        1001 = 9
  171. 0010 = 2        1010 = 10
  172. 0011 = 3        1011 = 11
  173. 0100 = 4        1100 = 12
  174. 0101 = 5        1101 = 13
  175. 0110 = 6        1110 = 14
  176. 0111 = 7        1111 = 15
  177.  
  178.     Each  byte describes the color of only 2  pixels.  But  again, 
  179. since there are only 320 pixels per line, and 200 vertical lines, 
  180. only 32,000 bytes are required to represent a full screen.
  181.  
  182. Figure 3-2 Organization of Color Screen Memory
  183.  
  184.    As mentioned previously, the ST is capable of displaying 512 
  185. colors, but only 16 colors may be displayed at one time (in low 
  186. resolution). Each value stored in color memory corresponds to a 
  187. hardware color register.
  188.      In GFA BASIC, the command COLOR defines the color to be used 
  189. by a graphics command. If you do not specify a color before a 
  190. graphics command, either the default color or the color last used 
  191. is selected. Usually, the default color is color 1, which has a 
  192. default value of black, 0.
  193.  
  194. Graphics Programming Techniques
  195.  
  196. Entire  books  have  been  written about  the  various  phases  of 
  197. computer graphics. Each section of this chapter could be dealt 
  198. with in much greater detail. Instead, we're going to introduce 
  199. you, quickly and painlessly, to graphics techniques, point you in 
  200. the right direction, and then leave you to the excitement of 
  201. discovery as you explore this world with your staunch ally, GFA 
  202. BASIC.
  203.    As with any voyage, some preliminary attention to detail must 
  204. be undertaken. After all, to use the graphics commands, you must 
  205. at least be able to tell the computer where you want the object 
  206. you're drawing to appear.
  207.      There are several coordinate systems in use, but the two most 
  208. common are the Cartesian coordinate system and the polar 
  209. coordinate system.
  210.      In the Cartesian coordinate system, the two-dimensional plane 
  211. is assigned two axes: the horizontal axis, usually labeled x, and 
  212. the vertical axis, Çusually labeled y. By convention, the positive 
  213. direction of the x-axis is to the right, but the positive 
  214. direction of the y-axis can be either up or down, depending on the 
  215. application. In geometry and most other mathematical applications, 
  216. the positive direction of the y-axis is up, but on most computer 
  217. systems, the positive direction is down. Points in the plane are 
  218. represented by ordered pairs (x,y), where x is the distance of the 
  219. point from the y-axis and y is the distance of the point from the 
  220. x-axis. The point (0,0) is called the origin because it is the 
  221. point where the x and y axes intersect, the point from which all 
  222. other points in the plane are located.
  223.   The location of the origin is another disputed aspect of the 
  224. Cartesian coordinate system. In geometry, the origin is 
  225. traditionally located in the lower left corner of the display with 
  226. the positive x and y axes extending toward the right and top of 
  227. the display, respectively. However, on most computers, the origin 
  228. is located in the upper left corner of the screen, because of the 
  229. way the monitor draws the display. Another possible location for 
  230. the origin is the center of the display. This orientation makes it 
  231. easy to graph both negative as well as positive values -- 
  232. something the other two systems ignore. Either of these locations 
  233. is equally valid, and conversion from one orientation to the other 
  234. is simple, so the choice of which system to use is usually left up 
  235. to the user.
  236.  
  237.  
  238. Figure 3-3. Cartesian Coordinate System
  239.  
  240.  
  241.  
  242. Figure 3-4 Polar Coordinate System
  243.  
  244.  
  245.    The Cartesian coordinate system cooresponds closely with the 
  246. real world, which makes it ideal for most applications, but in 
  247. situations where rotation is necessary, the Cartesian coordinate 
  248. system is difficult to use.    Two systems of referencing are in 
  249. common use with computers: the normalized device coordinate (NDC) 
  250. system, and the raster coordinate (RC) system
  251.  
  252. . The NDC system addresses the graphics display independent of the 
  253. device's display size, while the RC system addresses the device in 
  254. actual display units. The RC system is the system used on most 
  255. microcomputers. With this system, the screen is divided into rows 
  256. and columns of dots, or pixels. The pixels in the top row have a 
  257. vertical, or y, coordinate of 0. The y coordinate increases as you 
  258. move toward the bottom of the screen. The bottom row of the screen 
  259. has a y coordinate value of 199 on a color system and 399 on a 
  260. monochrome system. The leftmost column of pixels has a horizontal, 
  261. or x, coordinate of 0.
  262.  
  263.      The x coordinate increases as you move toward the right edge 
  264. of the display, where each pixel in the rightmost column has the 
  265. value of 319 on color systems in low resolution and 639 in medium 
  266. or high resolution.
  267.                Figure 3-5. Raster Coordinate System
  268.  
  269.  
  270.  
  271.      The ST also supports the NDC system. It's difficult to write 
  272. a single program that will work with the different types of 
  273. devices, because almost every graphics output device has a 
  274. different maximum horizontal and vertical resolution. That's where 
  275. the NDC system becomes expedient.
  276.    The NDC system offers the programmer a means by which graphics 
  277. drawn on one computer screen or printer will look the same when 
  278. drawn on other computer screens or printers of different 
  279. resolutions. With the NDC system, all graphics output is sent to 
  280. an imaginary device that is 32,768 pixels wide and 32,768 pixels 
  281. high. These pixels are grouped differently from those under the RC 
  282. system. The y axis begins with 0 at the bottom of the screen, and 
  283. moves up to the top row of pixels numbering 32,767. As in the RC 
  284. system, the x axis is numbered from left to right. The leftmost 
  285. column of pixels is 0, and the rightmost column is 32,767.
  286.    Two coordinate-referencing systems on one computer may seem 
  287. difficult to grasp, but usually you'll only be dealing with the RC 
  288. system in GFA BASIC. You should be aware of the NDC system, as it 
  289. does have value with GDOS and some VDI functions.
  290.  
  291. Figure 3-6. Normalized Device Coordinate (NDC) System
  292.  
  293.  
  294. Resolving a problem
  295.  
  296.      The ST may be configured in low resolution (320x200 pixels) 
  297. and medium resolution (640x200 pixels) with a color monitor, or in 
  298. high resolution (640x400 pixels) with a monochrome monitor. It's 
  299. very easy to include a simple check for the resolution mode, then 
  300. use program modules applicable for th resolution. It's even 
  301. possible to affect a change of resolution from GFA BASIC by using 
  302. an XBIOS function. At the very least, you should include a check 
  303. in your program to determine which mode of resolution the computer 
  304. is displaying. If necessary, you can then display an Alert box 
  305. informing the user that the program requires a different 
  306. resolution. Good programming practice dictates that your program 
  307. be compatible with different systems, if possible. Especially with 
  308. programs that use graphics, the effect you've labored to create 
  309. will be lost if the proper mode of resolution isn't selected.
  310.    XBIOS is a group of extended input/output functions which are 
  311. available to the programmer. For more information about XBIOS 
  312. routines, refer to Appendix F. GFA BASIC makes these functions 
  313. available to you by using the same bindings as those used by 
  314. programmers working in C. Refer to Appendix F for a list of the 
  315. XBIOS functions and bindings.
  316.    To check the resolution of a system, XBIOS 4, called getrez in 
  317. most literature about the ST, can be used.
  318.  
  319. PROCEDURE check_rez
  320.  '
  321.  rez=XBIOS(4)
  322.  '
  323. RETURN
  324.  
  325.    This  procedure  will  return  the  screen  resolution  in  the 
  326. variable, rez:
  327.  
  328. 0 = low resolution (320x200, 16 colors)
  329. 1 = medium resolution (640x200, 4 colors)
  330. 2 = high resolution (640x400, monochrome)
  331.  
  332.    To change resolution modes, use the following procedure. Define 
  333. rez  equal  to  the  value of the  desired  resolution  then  call 
  334. set_rez. (Note: high resolution is only available with a 
  335. monochrome monitor.)
  336.  
  337. PROCEDURE set_rez
  338.  '
  339.   dummy=XBIOS(5,L:-1,L:-1,W:rez)
  340.  '
  341. RETURN
  342.  
  343.    Switching from medium to low resolution will present no special 
  344. problems.  However, when you force a switch from low resolution to 
  345. medium resolution,  graphics commands will not appear on the right 
  346. side of the screen. The operating system still assumes that values 
  347. greater than 319 for X are off the screen.  Meanwhile all graphics 
  348. with X coordinates less than 320,  will be shown, on the left side 
  349. of  the  screen.  Using the PRINT command to display  text  should 
  350. present no problem.
  351.  
  352. GFA BASIC Graphics Commands
  353.  
  354.    As the following list of graphics commands illustrates, GFA 
  355. BASIC provides a powerful and easy to use programming enviornment. 
  356. More information about these commands can be found in Chapter Two, 
  357. GFA BASIC Commands and Functions or in Appendix A, Quick Reference 
  358. GFA BASIC Glossary.
  359.  
  360.  
  361. BITBLT
  362. BOX
  363. CIRCLE
  364. CLEARW
  365. CLOSEW
  366. CLS
  367. COLOR
  368. DEFFILL
  369. DEFLINE
  370. DEFMARK
  371. DEFMOUSE
  372. DRAW
  373. ELLIPSE
  374. FILL
  375. FULLW
  376. GET
  377. GRAPHMODE
  378. HARDCOPY
  379. HIDEM
  380. INFOW
  381. LINE
  382. MOUSE
  383. MOUSEX
  384. MOUSEY
  385. MOUSEK
  386. OPENW
  387. PBOX
  388. PCIRCLE
  389. PELLIPSE
  390. PRBOX
  391. PLOT
  392. POINT
  393. POLYLINE
  394. POLYFILL
  395. POLYMARK
  396. PUT
  397. RBOX
  398. SETCOLOR
  399. SGET
  400. SHOWM
  401. SPRITE
  402. SPUT
  403. TEXT
  404. TITLEW
  405. VSYNC
  406.  
  407.  
  408. Graphics on a 2-dimensional surface
  409.  
  410.    The simplest of the graphic commands in GFA BASIC are the  line 
  411. drawing commands. The simplest of these is the LINE command. 
  412. Remember, the coordinates used by the LINE command and the other 
  413. GFA BASIC graphics commands are in the Raster Coordinate (RC) 
  414. System.
  415.  
  416. Figure  3-7.  Simple  graphic produced by Program  3-1  using  GFA 
  417. BASIC.
  418.  
  419.    The following short program demonstrates the ease with which  a 
  420. simple graphic screen can be developed using the LINE and BOX 
  421. commands.
  422.    GFA BASIC listings for this book have been produced by first 
  423. selecting the dir item on the Editor's menu bar, then entering, 
  424. DEFLIST 0, which causes all commands and function to be displayed 
  425. (and printed LLIST) in all capitol letters. Variable names and 
  426. names of procedures will be in lower case letters. 
  427. Program  3-1 
  428. LINEDRAW.PRG
  429.  
  430.  
  431. ' Simple Line Drawing Demo
  432. '
  433. LINE 0,100,150,100
  434. LINE 500,100,640,100
  435. BOX 150,50,500,150
  436. LINE 325,25,150,50
  437. LINE 325,25,500,50
  438. BOX 295,80,355,150
  439. BOX 175,90,255,130
  440. LINE 215,90,215,130
  441. LINE 175,110,255,110
  442. BOX 390,90,470,130
  443. LINE 430,90,430,130
  444. LINE 390,110,470,110
  445. '
  446.  
  447.  
  448.    In order to make the screen a little more interesting, we'll 
  449. use DEFFILL to select a pattern style and colors to be used by the 
  450. FILL command. For more information about DEFFILL, or any other GFA 
  451. BASIC command, refer to Chapter Two. 
  452.  
  453. DEFFILL 3
  454. '
  455. FILL 5,195
  456. '
  457. DEFFILL 1,3
  458. FILL 330,30
  459. '
  460. DEFFILL 1,2
  461. FILL 5,5
  462. '
  463. DEFFILL 2,2
  464. FILL 155,55
  465. '
  466. DEFFILL 2,1
  467. FILL 310,115
  468.  
  469.  
  470.    The image produced will only flash on the screen, then 
  471. disappear as the edit screen reappears when the program ends . We 
  472. need to place GFA BASIC into a loop which repeats until we decide 
  473. it's time to exit the loop (and the program) and send a signal to 
  474. the interpretter. All that is needed is a REPEAT...UNTIL loop 
  475. which will wait for any key to be pressed. When a key is pressed, 
  476. the program ends.
  477.  
  478.  
  479. '
  480. REPEAT
  481. UNTIL INKEY$<>""
  482. END
  483.  
  484.  
  485.    Generally, we'll be discussing each routine used in a program, 
  486. rather than the individual commands used to obtain the desired 
  487. result. If a more detailed explanation of a command or function is 
  488. needed, refer to Chapter 2 or Appendix A.
  489.  
  490.  
  491. String Art
  492.  
  493. Only a short step from line drawing is an interesting art form, 
  494. String Art. String Art may be either a succession of points 
  495. connected by lines, or a  sequence of lines drawn on the screen. 
  496. Computer generated String Art may even take the form of lines 
  497. dancing around the screen, as in this program. STRING.BAS will 
  498. draw each screen and then wait for the user to press a key before 
  499. continuing. The last screen prompts the user for a positive 
  500. number. This number determines how many petals to draw on a rose.
  501.    Originally we intended this part to work only with integers, 
  502. but we discovered that some very interesting patterns develop if 
  503. you enter compound numbers (numbers with a fractional part). Try 
  504. several different values. STRING.BAS will display the rose for 
  505. each and then wait for you to press a key. If you'd like to stop 
  506. the drawing process to any time, press a key. When the drawing has 
  507. stopped, pressing a key will prompt you for a new number. Enter 0 
  508. to exit STRING.BAS. The LINE command is used to draw each of the 
  509. screens.
  510.  
  511. Program 3-2. String Art
  512.  
  513.    The first thing String Art does is check the current screen 
  514. resolution and set the global variables x_size and y_size to the 
  515. width and height of the screen, respectively.
  516.  
  517.  
  518. ' What resolution is the ST in?
  519. '   xbios(4) returns 0 if low ,  1 if medium,  and 2  if  high 
  520. resolution
  521. rez=XBIOS(4)
  522. '
  523. ' set x_size to the width and y_size to the height of the screen
  524. '
  525. IF rez=0
  526.  x_size=320
  527.  y_size=200
  528. ENDIF
  529. IF rez=1
  530.  x_size=640
  531.  y_size=200
  532. ENDIF
  533. IF rez=2
  534.  x_size=640
  535.  y_size=400
  536. ENDIF
  537. '
  538.  
  539.  
  540.    STRING.BAS is written so that each screen is drawn by a 
  541. separate procedure; this makes it easy to delete some of the 
  542. existing screens or add new ones of your own. After each screen is 
  543. drawn, STRING.BAS waits for any key to be pressed before it clears 
  544. the screen and draws the next screen.
  545.  
  546. GOSUB screen_1
  547. GOSUB wait_key
  548. CLS
  549. GOSUB screen_4
  550. GOSUB wait_key
  551. CLS
  552. GOSUB screen_2
  553. GOSUB wait_key
  554. CLS
  555. GOSUB screen_3
  556. GOSUB wait_key
  557. CLS
  558. GOSUB screen_5
  559. '
  560. END
  561.  
  562.  
  563.    The rest of STRING.BAS consists of the procedures used in 
  564. calculating or actually drawing the figures.
  565.  
  566.  
  567. '
  568. '
  569. ' PROCEDURE wait_key
  570. '
  571. '    This subroutine pauses the program until the user  presses  a 
  572. key.
  573. '
  574. PROCEDURE wait_key
  575.  REPEAT
  576.  UNTIL inkey$<>""
  577. RETURN              ! end of wait_key
  578.  
  579.  
  580.    The following procedure converts the radius and theta values of 
  581. polar coordinates to Cartesian coordinates. See the section on 
  582. coordinate systems earlier in this chapter for details.
  583.  
  584.  
  585. '
  586. '
  587. ' PROCEDURE polar_to_rect
  588. '
  589. '   This procedure converts from the polar coordinate system to the
  590. ' rectangular coordinate system. Pass r (radius) and theta to
  591. '  polar_to_rect  and  it will return the x and y  values  in  the GLOBAL
  592. ' VARIABLES x and y.
  593. '
  594. PROCEDURE polar_to_rect(r,theta)
  595.  x=r*COS(theta)
  596.  y=r*SIN(theta)
  597. RETURN              ! end of polar_to_rect
  598.  
  599.  
  600.    This routine is used to draw two of the screens in STRING.BAS, 
  601. by calculating the values necessary for the end points of the line 
  602. to trace a limacon. Procedure limacon is used in the procedures 
  603. screen --1 and screen --2. The first parameter of limacon is the 
  604. angle theta for which the radius is to be calculated. The next two 
  605. parameters are constants which modify the shape of the limacon. 
  606. You might find it interesting to play around with these constants.
  607.  
  608.  
  609. '
  610. '
  611. ' PROCEDURE limacon
  612. '
  613. '   This procedure returns the value of r (radius) necessary to draw
  614. '  a limacon given the angle of theta and two scaling  factors,  m and n.
  615. ' NOTE: r is a GLOBAL VARIABLE.
  616. '
  617. PROCEDURE limacon(theta,m,n)
  618.  r=m+n*COS(theta)
  619. RETURN             ! end of limacon
  620.  
  621.  
  622.    Procedure rose generates one of the prettiest patterns possible 
  623. using polar coordinates. Its output is used in screen 5.
  624.  
  625.  
  626. '
  627. '
  628. ' PROCEDURE rose
  629. '
  630. '   This procedure returns the value of r (radius) necessary to 
  631. draw
  632. ' a rose given the angle theta,  the number of leaves,  n,  and  a 
  633. scaling
  634. ' factor m. n determines the number of leaves in the rose. If n is 
  635. even,
  636. ' then the rose will have 2n petals;  if n is odd, there will be n 
  637. leaves.
  638. ' NOTE: r is a GLOBAL VARIABLE.
  639. '
  640. PROCEDURE rose(theta,n,m)
  641.  r=m*COS(n*theta)
  642. RETURN             
  643.  
  644.   end of rose denominator is used in screen --5 to  determine  how 
  645. much  of  the flower to draw.  The denominator  returned  by  this 
  646. procedure  is  used to calculate the upper limit of  the  function 
  647. before it is plotted.
  648.  
  649.  
  650. '
  651. '
  652. ' PROCEDURE denominator
  653. '
  654. '   This  routine returns the denominator of a number  with  a 
  655. fractional component.  
  656. '
  657. PROCEDURE denominator(num)
  658.  LOCAL k
  659.  LOCAL a
  660.  LOCAL b
  661.  '
  662.  k=1
  663.  found=0
  664.  a=num
  665.  GOSUB denom(a)
  666.  IF found=0
  667.   a=num/SQR(2)
  668.   GOSUB denom(a)
  669.  ENDIF
  670.  IF found=0
  671.   a=num/SQR(3)
  672.   GOSUB denom(a)
  673.  ENDIF
  674.  IF found=0
  675.   a=num/SQR(5)
  676.   GOSUB denom(a)
  677.  ENDIF
  678.  IF found=0
  679.   a=num/PI
  680.   GOSUB denom(a)
  681.  ENDIF
  682.  IF found=0
  683.   a=num/PI^2
  684.   GOSUB denom(a)
  685.  ENDIF
  686.  IF found=0
  687.   a=num/EXP(1)
  688.   GOSUB denom(a)
  689.  ENDIF
  690.  IF found=0
  691.   a=num*PI
  692.   k=PI
  693.   GOSUB denom(a)
  694.  ENDIF
  695.  IF found=0
  696.   a=num*PI^2
  697.   k=PI^2
  698.   GOSUB denom(a)
  699.  ENDIF
  700.  IF found=0
  701.   k=1
  702.  ENDIF
  703.  '
  704.  d=b*k
  705. RETURN
  706. '
  707. '
  708. ' PROCEDURE denom
  709. '
  710. '   This routine actually calculates the denominator of the fraction.
  711. '
  712. PROCEDURE denom(a)
  713.  LOCAL c
  714.  LOCAL dun
  715.  c=ABS(a)
  716.  b=1
  717.  REPEAT
  718.   dun=0
  719.   b=b/c
  720.   c=(1/c)-INT(1/c)
  721.   IF b>100000
  722.    dun=1
  723.   ENDIF
  724.  UNTIL c<1.0E-06 OR dun<>0
  725.  IF dun<>1
  726.   b=INT(b)
  727.   found=1
  728.  ENDIF
  729. RETURN
  730.  
  731.  
  732.    The remaining five procedures actually draw the screens. Each 
  733. of them is well documanted in the code so we won't go into detail 
  734. on them.
  735.  
  736.  
  737. '
  738. '
  739. ' PROCEDURE screen_1
  740. '
  741. '   This procedure draws the first screen using the procedures,
  742. ' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
  743. '
  744. PROCEDURE screen_1
  745.  LOCAL steps
  746.  LOCAL y_scale    !y scaling factor
  747.  LOCAL x_scale    !x scaling factor
  748.  LOCAL l_limit    !lower limit of funtion
  749.  LOCAL u_limit    !upper limit of function
  750.  LOCAL x_inc     !x or theta increment
  751.  IF rez=0
  752.   steps=1000*PI
  753.  ENDIF
  754.  IF rez=1
  755.   steps=2000*PI
  756.  ENDIF
  757.  IF rez=2
  758.   steps=4000*PI
  759.  ENDIF
  760.  '
  761.  y_scale=y_size/2
  762.  l_limit=0
  763.  u_limit=2*PI
  764.  x_scale=x_size/2
  765.  x_inc=x_scale/steps
  766.  '
  767.  FOR theta=l_limit TO u_limit STEP x_inc
  768.   GOSUB limacon(theta,y_scale*3/4,y_scale*3/4)
  769.   GOSUB polar_to_rect(r,theta)
  770.   x1=x
  771.   y1=y
  772.   GOSUB limacon(theta,y_scale*3/4,-y_scale*3/4)
  773.   GOSUB polar_to_rect(r,theta)
  774.   x2=x
  775.   y2=y
  776.   IF rez<>1
  777.    LINE x1+x_scale,y1+y_scale,x2+x_scale,y2+y_scale
  778.   ELSE
  779.    LINE x1*2+x_scale,y1+y_scale,x2*2+x_scale,y2+y_scale
  780.   ENDIF
  781.  NEXT theta
  782. RETURN             ! end of screen_1
  783. '
  784. '
  785. ' PROCEDURE screen_2
  786. '
  787. '   This procedure draws the second screen using the procedures,
  788. ' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
  789. '
  790. PROCEDURE screen_2
  791.  LOCAL steps
  792.  LOCAL y_scale    !y scaling factor
  793.  LOCAL x_scale    !x scaling factor
  794.  LOCAL l_limit    !lower limit of funtion
  795.  LOCAL u_limit    !upper limit of function
  796.  LOCAL x_inc     !x or theta increment
  797.  IF rez=0
  798.   steps=250*PI
  799.  ENDIF
  800.  IF rez=1
  801.   steps=500*PI
  802.  ENDIF
  803.  IF rez=2
  804.   steps=1000*PI
  805.  ENDIF
  806.  '
  807.  y_scale=y_size/2
  808.  l_limit=0
  809.  u_limit=2*PI
  810.  x_scale=x_size/(u_limit-l_limit)
  811.  x_inc=x_scale/steps
  812.  ' ferp
  813.  FOR theta=l_limit TO u_limit STEP x_inc
  814.   GOSUB limacon(theta,y_scale*9/14,y_scale)
  815.   GOSUB polar_to_rect(r,theta)
  816.   x1=x
  817.   y1=y
  818.   GOSUB limacon(theta,y_scale*9/14,-y_scale)
  819.   GOSUB polar_to_rect(r,theta)
  820.   x2=x
  821.   y2=y
  822.   IF rez<>1
  823.    LINE x2+x_size*15/16,y2+y_size/2,x1+x_size/16,y1+y_size/2
  824.   ELSE
  825.    LINE x2*2+x_size*15/16,y2+y_size/2,x1*2+x_size/16,y1+y_size/2
  826.   ENDIF
  827.  NEXT theta
  828. RETURN             ! end of screen_2
  829. '
  830. '
  831. ' PROCEDURE screen_3
  832. '
  833. '   This procedure draws the third screen using the procedures,
  834. ' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
  835. '
  836. PROCEDURE screen_3
  837.  LOCAL steps
  838.  LOCAL y_scale    !y scaling factor
  839.  LOCAL x_scale    !x scaling factor
  840.  LOCAL l_limit    !lower limit of funtion
  841.  LOCAL u_limit    !upper limit of function
  842.  LOCAL x_inc     !x or theta increment
  843.  IF rez=0
  844.   steps=500*PI
  845.  ENDIF
  846.  IF rez=1
  847.   steps=750*PI
  848.  ENDIF
  849.  IF rez=2
  850.   steps=1000*PI
  851.  ENDIF
  852.  '
  853.  y_scale=y_size/2
  854.  l_limit=0
  855.  u_limit=8*PI
  856.  x_scale=x_size/2
  857.  x_inc=x_scale/steps
  858.  '
  859.  FOR i=l_limit TO u_limit STEP x_inc
  860.   x1=SIN(i)+1
  861.   x2=SIN(i-3*PI/4)+1
  862.   y1=COS(i*3/4)+1
  863.   y2=COS((i-3*PI/4)*3/4)+1
  864.   LINE x1*x_scale,y1*y_scale,x2*x_scale,y2*y_scale
  865.   PAUSE 1
  866.  NEXT i
  867. RETURN             ! end of screen_3
  868. '
  869. '
  870. ' PROCEDURE screen_4
  871. '
  872. '   This procedure draws the fourth screen using the procedures,
  873. ' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
  874. '
  875. PROCEDURE screen_4
  876.  LOCAL steps
  877.  LOCAL y_scale    !y scaling factor
  878.  LOCAL x_scale    !x scaling factor
  879.  LOCAL l_limit    !lower limit of funtion
  880.  LOCAL u_limit    !upper limit of function
  881.  LOCAL x_inc     !x or theta increment
  882.  IF rez=0
  883.   steps=250*PI
  884.  ENDIF
  885.  IF rez=1
  886.   steps=500*PI
  887.  ENDIF
  888.  IF rez=2
  889.   steps=1000*PI
  890.  ENDIF
  891.  '
  892.  y_scale=y_size/2
  893.  l_limit=0
  894.  u_limit=5*PI
  895.  x_scale=x_size/2
  896.  x_inc=x_scale/steps
  897.  '
  898.  FOR i=l_limit TO u_limit STEP x_inc
  899.   x1=SIN(i)+1
  900.   x2=SIN(i-3*PI/4)+1
  901.   y1=COS(i*5/6)+1
  902.   y2=COS((i-3*PI/4)*5/6)+1
  903.   LINE x1*x_scale,y1*y_scale,x2*x_scale,y2*y_scale
  904.   PAUSE 1
  905.  NEXT i
  906. RETURN             ! end of screen_4
  907. '
  908. '
  909. ' PROCEDURE screen_5
  910. '
  911. '   This procedure draws the fifth screen using the procedures,
  912. ' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
  913. '
  914. PROCEDURE screen_5
  915.  LOCAL steps
  916.  LOCAL y_scale    !y scaling factor
  917.  LOCAL x_scale    !x scaling factor
  918.  LOCAL l_limit    !lower limit of funtion
  919.  LOCAL u_limit    !upper limit of function
  920.  LOCAL x_inc     !x or theta increment
  921.  IF rez=0
  922.   steps=500*PI
  923.  ENDIF
  924.  IF rez=1
  925.   steps=1000*PI
  926.  ENDIF
  927.  IF rez=2
  928.   steps=4000*PI
  929.  ENDIF
  930.  '
  931.  y_scale=y_size/2
  932.  l_limit=0
  933.  x_scale=x_size/2
  934.  '
  935.  PRINT "  This routine draws flowers with the"
  936.  PRINT "number of petals that you specify."
  937.  PRINT "If you enter an odd number, n, a flower"
  938.  PRINT "with n petals will be drawn. If you"
  939.  PRINT "enter an even number, n, a flower with"
  940.  PRINT "2n petals will be drawn. Flowers with"
  941.  PRINT "large numbers of petals look like"
  942.  PRINT "filled-in circles, so keep your number"
  943.  PRINT "small. You can stop the drawing at any"
  944.  PRINT "by pressing a key. When the drawing has"
  945.  PRINT "stopped, press any key to continue."
  946.  PRINT
  947.  REPEAT
  948.   INPUT "Input a positive number (0 to quit) ";n
  949.  UNTIL n>=0
  950.  WHILE n>0
  951.   CLS
  952.   u_limit=1
  953.   d=1
  954.   IF INT(n)<>n
  955.    found=0
  956.    GOSUB denominator(n)
  957.    u_limit=d
  958.   ENDIF
  959.   IF ODD(n*d) AND ODD(d)
  960.    u_limit=PI*u_limit
  961.   ELSE
  962.    u_limit=2*PI*u_limit
  963.   ENDIF
  964.   steps=2000*PI*n
  965.   x_inc=x_scale/steps
  966.   theta=l_limit
  967.   a$=""
  968.   WHILE theta<=u_limit AND a$=""
  969.    GOSUB rose(theta,n,y_scale)      ! rose returns r
  970.    GOSUB polar_to_rect(r,theta)     ! polar returns x and y
  971.    x1=x
  972.    y1=y
  973.    GOSUB rose(theta-PI/(3*n),n,y_scale)
  974.    GOSUB polar_to_rect(r,theta-PI/(3*n))
  975.    IF rez=1
  976.     LINE x1*2+x_scale,y1+y_scale,x*2+x_scale,y+y_scale
  977.    ELSE
  978.     LINE x1+x_scale,y1+y_scale,x+x_scale,y+y_scale
  979.    ENDIF
  980.    theta=theta+x_inc
  981.    a$=INKEY$
  982.   WEND
  983.   GOSUB wait_key
  984.   PRINT "Previous Number = ";n;" (";n*d;"/";d;")"
  985.   REPEAT
  986.    INPUT "Input a positive integer (0 to quit) ";n
  987.   UNTIL n>=0
  988.  WEND
  989. RETURN             ! end of screen_5
  990.  
  991.  
  992. Kaleidoscope
  993.  
  994.    Here's a colorful demonstration program reminiscent of the Lava 
  995. Lamps popular during the 1960s. You may have seen a version of ths 
  996. program  running  on the Commodore Amiga,  or even  a  C  language 
  997. version  on  th  ST.  KALEDIOSCOPE.BAS runs  from  the  GFA  BASIC 
  998. interpretter.  This program also demonstrates the use of some  new 
  999. graphic  commands.  Note  that "!" separates a  comment  from  the 
  1000. command on the same line.  Also, the ' mark is used in lines which 
  1001. contain only a comment.   In this program you'll see color spelled 
  1002. two ways; color and colour. Color is a GFA BASIC command which 
  1003. sets the color to be used by a graphics command, and the in-line 
  1004. Syntax checker will interpret it as such. Often to use a 
  1005. descriptive label or variable name, it's advantageous to 
  1006. deliberately mis-spell a word. Be sure to keep track of such mis-
  1007. spellings, and mis-spell the word the same way every time.
  1008.  
  1009. Program 3-3. KALEDIO.BAS
  1010.  
  1011.    Begin by reserving an area of memory to hold the alternate 
  1012. palette colors.   
  1013.  
  1014. DIM palette(15),pal(15),pal2(15)
  1015. '
  1016. shape=0          ! Initial shape is a circle.
  1017. HIDEM           ! Hide mouse
  1018. '
  1019. '
  1020. ' Check for low resolution
  1021. '
  1022. IF XBIOS(4)<>0
  1023.  alrt$="KALEIDOSCOPE only works in|Low Res (320X200 Pixels)"
  1024.  ALERT 3,alrt$,1,"Oops!!",b
  1025.  END
  1026. ENDIF
  1027.  
  1028.  
  1029.     Next,  set  up  an alternate  color  palette.  Each  color  is 
  1030. represented by three hexadecimal numbers,  representing the  three 
  1031. color guns of an RGB (Red, Green, and Blue) monitor, ranging from 
  1032. 0 for a gun which is turned off, to 7 for a gun at the highest 
  1033. output level. You can experiment with the numbers on the following 
  1034. table to observe the effects of different numbers on the display. 
  1035. (For more inforamtion about colors and the SETCOLOR command, refer 
  1036. to Chapter 2.)
  1037.    You can use the Control Panel desk accessory to get instant 
  1038. feedback on mixing colors. When you use it to mix colors using 
  1039. different levels of red, green, and blue, the panel displays these 
  1040. color levels as numbers from 0 to 7. The desktop, and the COntrol 
  1041. Panel, will change colors as you change the settings. It's best to 
  1042. write down the numbers displayed as you proceed, as it may become 
  1043. necessary to turn off your ST and reboot in order to restore a 
  1044. readable screen. Use these numbers as the hexadecimal values in 
  1045. the following table to install the colors in your color palette, 
  1046. as demonstrated below.
  1047.  
  1048.  
  1049. '
  1050. '
  1051. ' Set up color table
  1052. '
  1053. pal2(0)=&H555
  1054. pal2(1)=&H700
  1055. pal2(2)=&H60
  1056. pal2(3)=&H7
  1057. pal2(4)=&H5
  1058. pal2(5)=&H520
  1059. pal2(6)=&H50
  1060. pal2(7)=&H505
  1061. pal2(8)=&H222
  1062. pal2(9)=&H77
  1063. pal2(10)=&H55
  1064. pal2(11)=&H707
  1065. pal2(12)=&H505
  1066. pal2(13)=&H550
  1067. pal2(14)=&H770
  1068. pal2(15)=&H555
  1069. '
  1070.  
  1071.  
  1072.    Now we'll display an Alert box containing the program title and 
  1073. a few pieces of necessary preliminary information. Usually, you 
  1074. won't want to use an Alert box for displaying anything except a 
  1075. warning, but in this case very little information is required. 
  1076. Notice that as you type in the text for the variable alrt$ the 
  1077. screen will scroll to the left. When you move to the next line, a 
  1078. dollar sign is displayed at the point where the text exceeds the 
  1079. 80 character screen limit. This dollar sign signifies that more 
  1080. text exists on this line
  1081.  
  1082. .
  1083.  
  1084.  
  1085. '
  1086. ' Display title box
  1087. '
  1088. alrt$="    Kaleidoscope|Left Button  Restarts|Right  Button 
  1089. Changes Shape|Both Buttons End Program|"
  1090. ALERT 1,alrt$,1,"Okay",b
  1091. '
  1092.  
  1093.  
  1094.    Since we plan to tamper with the color scheme, it would only be 
  1095. polite to provide a means to reset the colors when we end our 
  1096. program.
  1097.  
  1098.  
  1099. GOSUB save_palette    '
  1100. ' Setcolor 0,5,5,5     ! Set background to gray.
  1101. '
  1102. GOSUB set_colour      ! Install new palette
  1103. '
  1104. start:           ! Here's the real starting point
  1105. '
  1106. GOSUB restore_palette   ! We want to restore colors for multiple runs
  1107. '              otherwise print might be hard to read.
  1108. CLS
  1109. '
  1110. ' Do some more start up stuff.
  1111. '
  1112. PRINT AT(1,10);
  1113. INPUT "How many pixels/step (1 to 10)";stp$
  1114. IF stp$=""
  1115.  GOTO start
  1116. ENDIF
  1117. stp=VAL(stp$)
  1118. '
  1119. IF stp<1 OR stp>10  ! Check for valid range.
  1120.  GOTO start
  1121. ENDIF
  1122. '
  1123. minr=stp
  1124. CLS
  1125. FOR colour=1 TO 12
  1126.  DEFTEXT colour,17
  1127.  GOSUB title
  1128. NEXT colour
  1129. c=0
  1130.  
  1131.  
  1132.     The next few lines determine the starting point for the  first 
  1133. item to be drawn.
  1134.  
  1135.  
  1136. x=INT(RND(1)*320)
  1137. x1=x
  1138. y=INT(RND(1)*179)+20
  1139. y1=y
  1140. r=minr
  1141. dr=1
  1142. '
  1143. ' Main program loop follows:
  1144. '
  1145. REPEAT
  1146.  '
  1147.  GOSUB new_x
  1148.  GOSUB new_y
  1149.  '
  1150.  DEFFILL c
  1151.  INC c
  1152.  IF c>15
  1153.   c=1
  1154.  ENDIF
  1155.  IF dr=1
  1156.   INC r
  1157.  ENDIF
  1158.  IF dr=0
  1159.   DEC r
  1160.  ENDIF
  1161.  IF r=20
  1162.   dr=0
  1163.  ENDIF
  1164.  IF r=minr
  1165.   dr=1
  1166.  ENDIF
  1167.  '
  1168.  
  1169.  
  1170.  
  1171. Now determine which shape,  circle or square to draw; then display 
  1172. that shape on the screen.
  1173.  
  1174.  
  1175.  
  1176.  IF shape=0
  1177.   PCIRCLE x,y,r
  1178.  ELSE
  1179.   PBOX x,y,x+r,y+r
  1180.  ENDIF
  1181.  '
  1182.  GOSUB change_colour
  1183.  '
  1184.  k=MOUSEK
  1185. UNTIL k<>0
  1186. '
  1187. ' Left mouse button pressed?
  1188. '
  1189. IF k=1
  1190.  GOTO start
  1191. ENDIF
  1192. '
  1193. ' Right Mouse button pressed?
  1194. '
  1195. IF k=2 AND shape=0
  1196.  shape=1        ! Change shape to rectangle
  1197.  GOTO start
  1198. ENDIF
  1199. '
  1200. IF k=2 AND shape=1
  1201.  shape=0        ! Change shape to circle
  1202.  GOTO start
  1203. ENDIF
  1204. '
  1205. PAUSE 35        ! System needs a sec or 2 here.
  1206. CLS
  1207. GOSUB restore_palette
  1208. SHOWM
  1209. END
  1210. '
  1211.  
  1212.  
  1213.    Now we need to find a new value for x.
  1214.  
  1215.  
  1216. '
  1217. PROCEDURE new_x
  1218.  '
  1219.  IF x1>=319
  1220.   SUB x,stp
  1221.  ELSE
  1222.   ADD x,stp
  1223.  ENDIF
  1224.  ADD x1,stp
  1225.  IF x1>=643
  1226.   x1=stp
  1227.   x=stp
  1228.  ENDIF
  1229. RETURN
  1230. '
  1231.  
  1232.  
  1233.    Next we need a new y value.
  1234.  
  1235.  
  1236. '
  1237. PROCEDURE new_y
  1238.  '
  1239.  IF y1>199
  1240.   SUB y,stp
  1241.  ELSE
  1242.   ADD y,stp
  1243.  ENDIF
  1244.  ADD y1,stp
  1245.  IF y1>375
  1246.   y1=28
  1247.   y=28
  1248.  ENDIF
  1249. RETURN
  1250. '
  1251.  
  1252.  
  1253.    The following procedure is a useful routine you'll see often in 
  1254. this  book.  It saves the palette as set up by the user  from  the 
  1255. Control Panel, so that the default colors may be restored when the 
  1256. program ends.
  1257.  
  1258.  
  1259. ' Save Original Color Palette
  1260. '
  1261. PROCEDURE save_palette
  1262.  LOCAL i
  1263.  '
  1264.  FOR i=0 TO 15
  1265.   palette(i)=XBIOS(7,W:i,W:-1)
  1266.   pal(i)=palette(i)
  1267.  NEXT i
  1268.  '
  1269. RETURN
  1270. '
  1271. '
  1272.  
  1273.  
  1274.    Here's the procedure which restores the default color  palette. 
  1275. You'll see this one used again, too.
  1276.  
  1277.  
  1278. '
  1279. ' Restore Original Color Palette
  1280. '
  1281. PROCEDURE restore_palette
  1282.  LOCAL i
  1283.  '
  1284.  FOR i=0 TO 15
  1285.   SETCOLOR i,palette(i)
  1286.  NEXT i
  1287. RETURN
  1288. '
  1289.  
  1290.  
  1291.      To give the illusion of constant movement on the screen, 
  1292. we're going to rotate the color palette. This procedure takes care 
  1293. of the rotation sequence.
  1294.  
  1295.  
  1296. PROCEDURE change_colour
  1297.  '
  1298.  temp=pal(1)
  1299.  FOR i=2 TO 15
  1300.   pal(i-1)=pal(i)
  1301.  NEXT i
  1302.  pal(15)=temp
  1303.  '
  1304.  FOR i=1 TO 15
  1305.   SETCOLOR i,pal(i)
  1306.  NEXT i
  1307.  FOR i=0 TO 15
  1308.   pal(i)=XBIOS(7,W:i,W:-1)
  1309.  NEXT i
  1310. RETURN
  1311. '
  1312.  
  1313.  
  1314.    Here is another routine to dazzle the beholder.  This procedure 
  1315. sets  up the title "Kaleidoscope" to alternate colors  with  color 
  1316. cycling.
  1317.  
  1318.  
  1319. PROCEDURE title
  1320.  IF colour=1
  1321.   TEXT 95,7,"K"
  1322.  ENDIF
  1323.  IF colour=2
  1324.   TEXT 105,7,"a"
  1325.  ENDIF
  1326.  IF colour=3
  1327.   TEXT 115,7,"l"
  1328.  ENDIF
  1329.  IF colour=4
  1330.   TEXT 125,7,"e"
  1331.  ENDIF
  1332.  IF colour=5
  1333.   TEXT 135,7,"i"
  1334.  ENDIF
  1335.  IF colour=6
  1336.   TEXT 145,7,"d"
  1337.  ENDIF
  1338.  IF colour=7
  1339.   TEXT 155,7,"o"
  1340.  ENDIF
  1341.  IF colour=8
  1342.   TEXT 165,7,"s"
  1343.  ENDIF
  1344.  IF colour=9
  1345.   TEXT 175,7,"c"
  1346.  ENDIF
  1347.  IF colour=10
  1348.   TEXT 185,7,"o"
  1349.  ENDIF
  1350.  IF colour=11
  1351.   TEXT 195,7,"p"
  1352.  ENDIF
  1353.  IF colour=12
  1354.   TEXT 205,7,"e"
  1355.  ENDIF
  1356. RETURN
  1357. '
  1358.  
  1359.  
  1360.    The set_color procedure is used to install our custom palette 
  1361. when the program intializes.
  1362.  
  1363.  
  1364. PROCEDURE set_colour
  1365.  FOR i=0 TO 15
  1366.   dummy=XBIOS(7,pal2(i))
  1367.  NEXT i
  1368. RETURN
  1369.  
  1370.  
  1371.  
  1372. The Dragon Plot
  1373.  
  1374. Fractals  have  been  receiving  a  great  deal  of  attention  in 
  1375. mathematics  and  computer  graphics.   They're  being  used   for 
  1376. everything from simulating random plant growth to generating 
  1377. realistic planetary landscapes in science fiction films.
  1378.      Understanding fractals may not be as exciting as seeing them 
  1379. in action, but some explanation should prove helpful to your 
  1380. programming. The word fractal Çwas coined by Benoit Mandelbrot, a 
  1381. pioneer in their study, to denote curves or surfaces having 
  1382. fractional dimension. The idea of fractional dimension can be 
  1383. illustrated as a straight curve (a line) which has only one- 
  1384. dimension, length. If the curve is infinitely long and curves in 
  1385. such a manner that it completely fills an area of the plane 
  1386. containing it, the curve can be considered two-dimensional. A 
  1387. curve partially filling an area has a fractional dimension between 
  1388. 1 and 2.
  1389.    Many types of fractals are self-similar. This means that all 
  1390. portions of the fractal resemble each other. This occurs whenever 
  1391. the whole is an expansion of some basic building block. In the 
  1392. language of fractals, this basic building block is called the 
  1393. generator.
  1394.   The generator in the next program consists of a number of 
  1395. connected line segments.The curves plotted by this program are the 
  1396. result of starting with the generator and then repeatedly 
  1397. replacing each line segment, according to a defined rule. The 
  1398. number of cycles is limited by the screen resolution. Select too 
  1399. high a number of cycles, and the program will also slow down to a 
  1400. crawl. Eventually, the screen will be filled by the fractal 
  1401. generator, as portions are plotted off the screen as well.
  1402.   This simple program which begins our exploration of the world of 
  1403. fractals plots a particular type of fractal which Mandelbrot 
  1404. labeled a "dragon plot." This program illustrates a self-
  1405. contacting curve. A self-contacting curve touches, but does not 
  1406. cross, itself. The generator consists of two-line segments of 
  1407. equal length forming a right angle. During each cycle, the 
  1408. generator is substituted for each segment on alternating sides of 
  1409. the segments. (Even though GFA BASIC executes faster than most 
  1410. interpreted languages, it's still slow, and that's part of the 
  1411. fascination of the dragon plot --watching as your ST plots the 
  1412. figure, and noting the areas of similarity.
  1413.    DRAGON.BAS begins by asking you to enter an even number of 
  1414. cycles. When a plot is complete, pressing any key clears the 
  1415. screen and returns you to the starting prompt. Try starting out 
  1416. with two cycles, then four, then six, and so on.  As you add more 
  1417. cycles, more time is required to fill in the dragon.
  1418.  
  1419.  
  1420. Program 3-4. DRAGON.BAS
  1421.  
  1422.  
  1423. DIM sn(20)
  1424. in:
  1425. CLS
  1426. PRINT "Enter an even number of cycles (2-20)"
  1427. INPUT "or enter a zero to quit: ";nc$
  1428. nc=VAL(nc$)
  1429. IF nc=0
  1430.  END
  1431. ENDIF
  1432. IF nc<2 OR nc>20
  1433.  GOTO in
  1434. ENDIF
  1435. IF EVEN(nc)<>-1
  1436.  GOTO in
  1437. ENDIF
  1438. l=128
  1439. FOR c=2 TO nc STEP 2
  1440.  l=l/2
  1441. NEXT c
  1442. x=85
  1443. y=100
  1444. CLS
  1445. COLOR 3
  1446. PLOT x,y
  1447. FOR c=0 TO nc
  1448.  sn(c)=0
  1449. NEXT c
  1450. rot_seg:
  1451. d=0
  1452. FOR c=1 TO nc
  1453.  IF sn(c-1)=sn(c)
  1454.   d=d-1
  1455.   GOTO rotate_it
  1456.  ENDIF
  1457.  d=d+1
  1458.  rotate_it:
  1459.  IF d=-1
  1460.   d=7
  1461.  ENDIF
  1462.  IF d=8
  1463.   d=0
  1464.  ENDIF
  1465. NEXT c
  1466. IF d=0
  1467.  x=x+l+l
  1468.  GOTO seg
  1469. ENDIF
  1470. IF d=2
  1471.  y=y+l
  1472.  GOTO seg
  1473. ENDIF
  1474. IF d=4
  1475.  x=x-l-l
  1476.  GOTO seg
  1477. ENDIF
  1478. y=y-l
  1479. seg:
  1480. COLOR 3
  1481. DRAW TO x,y
  1482. sn(nc)=sn(nc)+1
  1483. FOR c=nc TO 1 STEP -1
  1484.  IF sn(c)<>2
  1485.   c=1
  1486.   GOTO next_seg
  1487.  ENDIF
  1488.  sn(c)=0
  1489.  sn(c-1)=sn(c-1)+1
  1490.  next_seg:
  1491. NEXT c
  1492. IF sn(0)=0
  1493.  GOTO rot_seg
  1494. ENDIF
  1495. PRINT AT(7,23);"Press any key to continue"
  1496. REPEAT
  1497. UNTIL INKEY$<>""
  1498. GOTO in
  1499.  
  1500.  
  1501.  
  1502. The Mandelbrot Set
  1503.  
  1504.      You can see fractals in nature in many places. The clouds, 
  1505. coastlines displayed in satellite photographs, and even a leaf 
  1506. will reveal fractals. We've seen one form of computer-generated 
  1507. fractals in Program 3-5, the dragon sweep. Now we'll explore one 
  1508. of the strangest and most beautiful areas of fractal geometry, the 
  1509. Mandelbrot set.
  1510.    The Mandelbrot set consists of complex numbers, numbers with a 
  1511. "real" and "imaginary" part. These terms, real and imaginary, have 
  1512. historical significance in mathematics, but are no longer 
  1513. relevant. A complex number takes the form of 6 + 3i; 6 is the real 
  1514. part of the number, and 3i represents the imaginary part (hence 
  1515. the i). Each complex number can be represented by a point on the 
  1516. two-dimensional plane.
  1517.    The Mandelbrot set is located at the center of a two-
  1518. dimensional sheet of numbers called the complex plane. When a 
  1519. specific operation is applied repeatedly to the numbers, the 
  1520. numbers outside the set retreat to infinity. The remaining numbers 
  1521. move about within the plane. Near the edge of the set, the numbers 
  1522. move about in a pattern which marks the beginning of the area of 
  1523. instability. This area is astonishingly beautiful, complex, 
  1524. infinitely variable, and yet somehow, strangely similiar.
  1525.    The unique factor in numbers within the Mandelbrot set is that 
  1526. values in the set never grow larger than 2 as the mathematical 
  1527. operation is performed on them. Points within the Mandelbrot set 
  1528. are represented in our program by black pixels. The colors of the 
  1529. other points are determined by counting the number of times each 
  1530. complex number is operated on before its value exceeds 2. This 
  1531. count is converted into a color.
  1532.    For more information on the theory of fractals, see The Fractal 
  1533. Geometry of Nature, by Benoit Mandelbrot.
  1534.  
  1535.  
  1536. Figure 3-8. The Mandelbrot Primitive
  1537.  
  1538.   Figure 3-8 shows a representation of the entire Mandelbrot set. 
  1539. You can reproduce this figure by running MANDELBROT.BAS, and 
  1540. selecting 100 iterations, an X Center of .75, and a Y Center of 0. 
  1541. Choose a range of 2 for viewing the complete image. Once you've 
  1542. become somewhat familiar with the general coordinates of the 
  1543. Mandelbrot set, try exploring the boundary area by selecting x and 
  1544. y coordinates located on the boundary, and then selecting smaller 
  1545. values for the range.   Program 3-5, MANDELBROT.BAS, was used to 
  1546. generate the image displayed in Figures 3-8, 3-9, and 3-10. Only a 
  1547. black-and-white representation was possible in the book, but the 
  1548. set generated by Program 3-5 is quite colorful.    Some other 
  1549. interesting areas to explore follow.
  1550.  
  1551. Figure 3-9. Mandelbrot Figure
  1552.  
  1553. Figure 3-10. Another Segment of the Mandelbrot Boundary.
  1554.  
  1555.  
  1556.  
  1557. X-Center   Y-Center    Range
  1558.   -1       0.32        0.3
  1559.   -1       0.2895      0.0005
  1560.   -0.97    0.276       0.0001
  1561.  
  1562.  
  1563.  
  1564.      In this program, we'll be introducing several new procedures 
  1565. which can be used in your own programs. We'll show you later how 
  1566. to merge these procedures into your programs.
  1567.  
  1568.  
  1569. Program 3-5. MANDELBROT.BAS
  1570.  
  1571.  
  1572. DIM palette(15),pal2(15)
  1573.  
  1574.    The mouse pointer will be in the way on the picture,  so  we'll 
  1575. just turn it off.
  1576.  
  1577.  
  1578. '
  1579. HIDEM
  1580. '
  1581.  
  1582.  
  1583.    We'll check to see which resolution is in use, then give a 
  1584. warning if the machine isn't in low resolution. This program will 
  1585. work in any resolution; it just looks best with 16 colors, so 
  1586. we'll allow it to continue if the user doesn't want to quit.
  1587.  
  1588.  
  1589. '
  1590. rez=XBIOS(4)
  1591. IF rez<>0
  1592.  alrt$="Fractals look best in|Low Resolution"
  1593.  ALERT 1,alrt$,1,"Continue|Quit",b
  1594.  IF b=2
  1595.   END
  1596.  ENDIF
  1597. ENDIF
  1598. '
  1599.  
  1600.  
  1601.     Next  we'll  establish default  values  for  different  screen 
  1602. resolutions.
  1603.  
  1604.  
  1605.  
  1606. IF rez=0
  1607.  screen_height=200      ! Low res screen 
  1608.  screen_width=320       
  1609. ENDIF
  1610. '
  1611. IF rez=1            ! Medium resolution screen
  1612.  screen_height=200
  1613.  screen_width=640
  1614. ENDIF
  1615. '
  1616. IF rez=2            ! High resolution screen
  1617.  screen_height=400
  1618.  screen_width=640
  1619. ENDIF
  1620. '
  1621. ' Main Loop begins here
  1622. '
  1623.  
  1624.  
  1625.    We've used this routine before. It saves the palette so you can 
  1626. restore the original colors later. It's a good programming 
  1627. practice to clean up after yourself. If you change the palette, 
  1628. then exit to the GFA BASIC editor, you may find yourself stuck on 
  1629. a screen that is impossible to read.
  1630.  
  1631.  
  1632. GOSUB save_palette
  1633. '
  1634.  
  1635.  
  1636.    Here's the main loop which controls the program.
  1637.  
  1638.  
  1639. DO
  1640.  '
  1641.  GOSUB values
  1642.  IF rez=0
  1643.   GOSUB set_new_colors
  1644.  ENDIF
  1645.  GOSUB calculate
  1646.  IF rez=0
  1647.   GOSUB restore_palette
  1648.  ENDIF
  1649.  GOSUB display_it
  1650.  '
  1651. LOOP
  1652.  
  1653.  
  1654.    We'll put an END in here, but the program never really exits 
  1655. from the DO...LOOP. Other procedures are called and executed from 
  1656. procedures called by the DO...LOOP, but everything within this 
  1657. program actually occurs within this loop.
  1658.  
  1659.  
  1660. '
  1661. END
  1662. '
  1663.  
  1664.  
  1665.    display_it is a procedure which displays information about the 
  1666. calculations for this particular portion of the Mandelbrot set and 
  1667. offers some options which may be selected by pressing a key. 
  1668. Usually this procedure will be encountered after the calculations 
  1669. for displaying the fractal are complete.
  1670.  
  1671. PROCEDURE display_it
  1672.  '
  1673.  display:
  1674.  CLS
  1675.  PRINT AT(1,3);"Fractal Image"
  1676.  PRINT AT(1,5);count;" Iterations Calculated."
  1677.  seconds=INT((time_finish-time_start)/2)/100
  1678.  min=INT(seconds/60)
  1679.  IF min<=0
  1680.   min=0
  1681.  ENDIF
  1682.  seconds=ABS(INT((seconds MOD 60)*100)/100)
  1683.  PRINT AT(1,7);min;" Minutes and ";seconds;" Seconds required."
  1684.  PRINT AT(1,8);"Number of iterations: ";iteration_limit
  1685.  PRINT AT(1,10);"X Center: ";x_center
  1686.  PRINT AT(1,11);"Y Center: ";y_center
  1687.  PRINT AT(1,12);"Scaling factor: ";range
  1688.  PRINT AT(1,14);"Minimum real value (xmin): ";real_min
  1689.  PRINT AT(1,15);"Maximum real value (xmax): ";real_max
  1690.  PRINT AT(1,16);"Minimum imaginary value (ymin): ";imag_min
  1691.  PRINT AT(1,17);"Maximum Imaginary value (ymax): ";imag_max
  1692.  PRINT AT(1,19);"Press:"
  1693.  PRINT AT(5,20);"<V> to View Fractal"
  1694.  PRINT AT(5,21);"<P> to Plot new Fractal"
  1695.  PRINT AT(5,22);"<S> to Save .NEO file"
  1696.  PRINT AT(5,23);"<Q> to Quit"
  1697.  '
  1698.  
  1699.  
  1700.    key waits for the user to press a key. Then the key value is 
  1701. stored in a$, and evaluated, and the proper branch is taken. UPPER 
  1702. is a GFA BASIC command which converts any value in a$ to 
  1703. uppercase. For more information about any GFA BASIC commands, 
  1704. refer to Chapter 2.
  1705.  
  1706.  
  1707.  key:
  1708.  REPEAT
  1709.   a$=INKEY$
  1710.  UNTIL a$<>""
  1711.  '
  1712.  IF UPPER$(a$)="V"
  1713.   SGET screen2$
  1714.   IF rez=0
  1715.    GOSUB set_new_colors
  1716.   ENDIF
  1717.   SPUT screen1$
  1718.   REPEAT
  1719.   UNTIL INKEY$<>""
  1720.   GOSUB restore_palette
  1721.   SPUT screen2$
  1722.  ENDIF
  1723.  '
  1724.  IF UPPER$(a$)="P"
  1725.   GOTO finito
  1726.  ENDIF
  1727.  '
  1728.  IF UPPER$(a$)="Q"
  1729.   SHOWM
  1730.   CLS
  1731.   END
  1732.  ENDIF
  1733.  '
  1734.  IF UPPER$(a$)="S"
  1735.   '
  1736.  
  1737.  
  1738.    Here's a handy procedure that saves the screen into a 
  1739. NEOchrome-compatible file. Following this program, we'll give you 
  1740. a simple routine which can be merged with your programs, and show 
  1741. you how you can use this routine to load screens in your own 
  1742. programs. 
  1743.  
  1744.   IF rez<>0
  1745.    CLS
  1746.    ALRT$="Must be Low Res|for Neochrome files"
  1747.    ALERT 1,alrt$,1,"OKAY",b
  1748.   ENDIF
  1749.   GOTO not_neo
  1750.   '
  1751.   SGET screen2$
  1752.   default$="C:\*.NEO"
  1753.   FILESELECT default$,"",infile$
  1754.   CLS
  1755.   IF infile$=""           !equals "" if CANCEL selected
  1756.    GOTO not_neo
  1757.   ENDIF
  1758.   GOSUB set_new_colors
  1759.   SPUT screen1$
  1760.   OPEN "o",#1,infile$
  1761.   '
  1762.   ' First two bytes to zero
  1763.   '
  1764.   FOR i=0 TO 2
  1765.    OUT #1,0
  1766.    OUT #1,0
  1767.   NEXT i
  1768.   '
  1769.   ' Save color palette
  1770.   '
  1771.   FOR i=0 TO 15
  1772.    hi=INT(pal2(i)/256)
  1773.    lo=pal2(i)-256*hi
  1774.    OUT #1,hi
  1775.    OUT #1,lo
  1776.   NEXT i
  1777.   '
  1778.   ' Color cycling info (not needed)
  1779.   '
  1780.   FOR i=0 TO 89
  1781.    OUT #1,0
  1782.   NEXT i
  1783.   '
  1784.   ' Save screen info
  1785.   '
  1786.   BPUT #1,XBIOS(3),32000
  1787.   '
  1788.   CLOSE
  1789.   SPUT screen2$
  1790.   GOSUB restore_palette
  1791.   '
  1792.   not_neo:
  1793.   '
  1794.  ENDIF
  1795.  '
  1796.  GOTO display
  1797.  '
  1798.  finito:
  1799.  RETURN
  1800. '
  1801.  
  1802.  
  1803.    values accepts input from the user for the values to be 
  1804. examined for the Mandelbrot boundaries.
  1805.  
  1806.  
  1807. PROCEDURE values
  1808.  '
  1809.  CLS
  1810.  INPUT "Number of iterations";iteration_limit
  1811.  INPUT "Center X";x_center
  1812.  INPUT "Center Y";y_center
  1813.  INPUT "Scale Range";range
  1814.  real_min=x_center-(range/2)
  1815.  real_max=x_center+(range/2)
  1816.  imag_max=y_center+((range/2)*0.77)
  1817.  imag_min=y_center-((range/2)*0.77)
  1818.  CLS
  1819. RETURN
  1820. '
  1821.     The next procedure does the real work.  The complex number  is 
  1822. evaluated as defined. Several arbitary values were selected for 
  1823. constants. You may find it interesting to change values, such as 
  1824. max_limit, to observe any changes in the figure plotted. 
  1825. time_start is used to calculate the time it took to complete the 
  1826. plot.
  1827.    Note that even though GFA BASIC is one of the fastest 
  1828. interpreters available, fractals can take a lot of time to plot. 
  1829. Most designs will take over an hour to complete. The closer the 
  1830. complex numbers are to the Mandelbrot set, the more calculations 
  1831. are required before the result exceeds 2. Therefore, more time is 
  1832. required.
  1833.  
  1834.  
  1835. PROCEDURE calculate
  1836.  '
  1837.  time_start=INT(TIMER)
  1838.  max_limit=100000000
  1839.  count=0
  1840.  real=(real_max-real_min)/(screen_width-1)
  1841.  imaginary=(imag_max-imag_min)/(screen_height-1)
  1842.  FOR y=0 TO screen_height
  1843.   FOR x=0 TO screen_width
  1844.    lreal=real_min+x*real
  1845.    limag=imag_min+y*imaginary
  1846.    re=lreal
  1847.    im=limag
  1848.    depth=0
  1849.    calc_loop:
  1850.    INC count
  1851.    x1=re^2
  1852.    y1=im^2
  1853.    im=2*re*im-limag
  1854.    re=x1-y1-lreal
  1855.    INC depth
  1856.    IF ((depth=iteration_limit) OR ((x1+y1)>max_limit))
  1857.     GOTO finished_yet
  1858.    ELSE
  1859.     GOTO calc_loop
  1860.    ENDIF
  1861.    finished_yet:
  1862.    IF (depth<iteration_limit)
  1863.     GOSUB draw_point
  1864.    ENDIF
  1865.  
  1866.  
  1867.    Since we can get stuck here waiting on the calculations for a 
  1868. long time, this will offer a way out and allow us a means to check 
  1869. on the time spent and calculations completed on this particular 
  1870. set of complex numbers.
  1871.  
  1872.  
  1873.    IF INKEY$<>""
  1874.     GOSUB break
  1875.    ENDIF
  1876.   NEXT x
  1877.  NEXT y
  1878.  '
  1879.  ' Save screen into screen1$
  1880.  '
  1881.  SGET screen1$
  1882.  '
  1883.  time_finish=INT(TIMER)     ! time of completion
  1884.  '
  1885. RETURN
  1886. '
  1887.  
  1888.  
  1889.    If a key is pressed, we must stop to evaluate it. We'll also 
  1890. display an interim screen with some interesting information. 
  1891.  
  1892. PROCEDURE break
  1893.  '
  1894.  SGET screen1$
  1895.  time_finish=INT(TIMER)
  1896.  IF rez=0
  1897.   GOSUB restore_palette
  1898.  ENDIF
  1899.  CLS
  1900.  PRINT AT(1,3);"Fractal Image"
  1901.  PRINT AT(1,5);count;" Iterations Calculated."
  1902.  seconds=INT((time_finish-time_start)/2)/100
  1903.  min=INT(seconds/60)
  1904.  IF min<=0
  1905.   min=0
  1906.  ENDIF
  1907.  seconds=ABS(INT((seconds MOD 60)*100)/100)
  1908.  PRINT AT(1,7);min;" Minutes and ";seconds;" Seconds required."
  1909.  PRINT AT(1,8);"Number of iterations: ";iteration_limit
  1910.  PRINT AT(1,10);"X Center: ";x_center
  1911.  PRINT AT(1,11);"Y Center: ";y_center
  1912.  PRINT AT(1,12);"Scaling factor: ";range
  1913.  PRINT AT(1,14);"Minimum real value (xmin): ";real_min
  1914.  PRINT AT(1,15);"Maximum real value (xmax): ";real_max
  1915.  PRINT AT(1,16);"Minimum imaginary value (ymin): ";imag_min
  1916.  PRINT AT(1,17);"Maximum Imaginary value (ymax): ";imag_max
  1917.  PRINT AT(1,19);"Press:"
  1918.  PRINT AT(5,20);"<C> to Continue Plot"
  1919.  PRINT AT(5,21);"<E> to Return to Main Menu"
  1920.  '
  1921.  keyit:
  1922.  REPEAT
  1923.   a$=INKEY$
  1924.  UNTIL a$<>""
  1925.  '
  1926.  IF UPPER$(a$)="E"
  1927.   x=screen_width
  1928.   y=screen_height
  1929.   SPUT screen1$
  1930.   GOTO finit
  1931.  ENDIF
  1932.  '
  1933.  IF UPPER$(a$)="C"
  1934.   IF rez=0
  1935.    GOSUB set_new_colors
  1936.   ENDIF
  1937.   SPUT screen1$
  1938.   GOTO finit
  1939.  ENDIF
  1940.  '
  1941.  GOTO keyit
  1942.  '
  1943.  finit:
  1944. RETURN
  1945.  
  1946.    The calculations are completed; now it's time to plot the 
  1947. point. Depth is equal to the number of iterations calculated on 
  1948. the number which represents the point. 
  1949.  
  1950. '
  1951. PROCEDURE draw_point
  1952.  '
  1953.  colour=depth MOD 16
  1954.  COLOR colour
  1955.  IF (depth>100)
  1956.   PLOT x,y
  1957.  ELSE
  1958.   GOSUB greater_than_two
  1959.  ENDIF
  1960. RETURN
  1961. '
  1962. PROCEDURE greater_than_two
  1963.  '
  1964.  IF depth MOD 2
  1965.   PLOT x,y
  1966.  ENDIF
  1967. RETURN
  1968. '
  1969.  
  1970.  
  1971.    set_new_colors changes the color palette by installing the 
  1972. colors we've selected into the hardware register for the palette.
  1973.  
  1974.  
  1975. PROCEDURE set_new_colors
  1976.  '
  1977.  ' Set up color table
  1978.  '
  1979.  pal2(0)=&H0
  1980.  pal2(1)=&H75
  1981.  pal2(2)=&H765
  1982.  pal2(3)=&H401
  1983.  pal2(4)=&H410
  1984.  pal2(5)=&H530
  1985.  pal2(6)=&H241
  1986.  pal2(7)=&H62
  1987.  pal2(8)=&H474
  1988.  pal2(9)=&H744
  1989.  pal2(10)=&H731
  1990.  pal2(11)=&H165
  1991.  pal2(12)=&H14
  1992.  pal2(13)=&H750
  1993.  pal2(14)=&H423
  1994.  pal2(15)=&H601
  1995.  '
  1996.  '
  1997.  FOR i=0 TO 15
  1998.   SETCOLOR i,pal2(i)
  1999.  NEXT i
  2000. RETURN
  2001. '
  2002.  
  2003.  
  2004.    We've seen the next two procedures before.
  2005.  
  2006. '
  2007. ' Save Original Color Palette
  2008. '
  2009. PROCEDURE save_palette
  2010.  LOCAL i
  2011.  '
  2012.  '
  2013.  FOR i=0 TO 15
  2014.   palette(i)=XBIOS(7,W:i,W:-1)
  2015.  NEXT i
  2016. RETURN
  2017. '
  2018. '
  2019. '
  2020. ' Restore Original Color Palette
  2021. '
  2022. PROCEDURE restore_palette
  2023.  LOCAL i
  2024.  '
  2025.  FOR i=0 TO 15
  2026.   SETCOLOR i,palette(i)
  2027.  NEXT i
  2028. RETURN
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035. Saving a Screen in NEOchrome Format
  2036.  
  2037. Here's a simple little routine similar to the one used in 
  2038. MANDELBROT.BAS. This program can easily be merged with any of your 
  2039. programs.
  2040.  
  2041. Program 3-6. NEOWRITE.BAS
  2042.  
  2043. Procedure Save_neoscreen
  2044. 'Reserve an area of memory for the alternate palette.
  2045.  
  2046.  '
  2047.  Dim Pal2(15)
  2048.  '
  2049.  Gosub Save_palette
  2050.  Hidem
  2051.  '
  2052.  Sget Screen1$
  2053.  '
  2054.  Rez=Xbios(4)
  2055.  If Rez<>0
  2056.   Cls
  2057.   Print ''Must be Low Resolution for Neochrome''
  2058.   Repeat
  2059.   Until Inkey$<>''''
  2060.   Cls
  2061.   Sput Screen1$
  2062.   Goto Not_neo
  2063.  Endif
  2064.  '
  2065.  Default$=''A:\*.NEO''
  2066.  Fileselect Default$,'''',Infile$
  2067.  Cls
  2068.  Sput Screen1$
  2069.  Open ''o'',#1,Infile$
  2070.  '
  2071.  ' First three words to zero
  2072.  '
  2073.  For I=0 To 2
  2074.   Out #1,0
  2075.   Out #1,0
  2076.  Next I
  2077.  '
  2078.  ' Save color palette
  2079.  '
  2080.  For I=0 To 15
  2081.   Hi=Int(Pal2(I)/256)
  2082.   Lo=Pal2(I)-256*Hi
  2083.   Out #1,Hi
  2084.   Out #1,Lo
  2085.  Next I
  2086.  '
  2087.  ' Color cycling info (not needed)
  2088.  '
  2089.  For I=0 To 89
  2090.   Out #1,0
  2091.  Next I
  2092.  '
  2093.  ' Save screen info
  2094.  '
  2095.  Bput #1,Xbios(3),32000
  2096.  '
  2097.  Close
  2098.  '
  2099.  Not_neo:
  2100.  '
  2101. Endif
  2102. '
  2103. '
  2104. Finito:
  2105. '
  2106. Return
  2107. '
  2108. ' Save Original Color Palette
  2109. '
  2110. Procedure Save_palette
  2111. Local I
  2112. '
  2113. '
  2114. '
  2115. For I=0 To 15
  2116.  Pal2(I)=Xbios(7,W:I,W:-1)
  2117. Next I
  2118. Return
  2119. '
  2120.  
  2121.  
  2122. After you've saved a screen in a NEOchrome format,  you'll need  a 
  2123. routine to display the screen without loading NEOCHROME.PRG. 
  2124. Here's a routine to load any NEOchrome-format screen. With a minor 
  2125. alteration, you may load any screen into your programs without 
  2126. using the fileselector box.
  2127.  
  2128. Program 3-7. NEOLOAD.BAS
  2129.  
  2130.  
  2131.  
  2132. DIM palette(15),pal2(15)
  2133. '
  2134. GOSUB save_palette
  2135. '
  2136.  
  2137.  
  2138.      Here's the main loop. Use these procedures as applicable in 
  2139. your program to load .NEO files. Refer to the user's guide for 
  2140. DEGAS Elite for information on how to handle a DEGAS file. It's 
  2141. just as simple.
  2142.  
  2143.  
  2144. main:
  2145. '
  2146. GOSUB check_rez
  2147. GOSUB choose_pic
  2148. HIDEM
  2149. GOSUB load_colour
  2150. GOSUB install_colour
  2151. GOSUB show_pic
  2152. '
  2153. g$=''''
  2154. REPEAT
  2155.  g$=INKEY$
  2156. UNTIL g$<>''''
  2157. '
  2158. CLS
  2159. '
  2160. GOSUB restore_palette
  2161. '
  2162. IF UPPER$(g$)=''Q''
  2163.  END
  2164. ENDIF
  2165. '
  2166. SHOWM
  2167. GOTO main
  2168. '
  2169. '
  2170. PROCEDURE check_rez
  2171.  '
  2172.  rez=XBIOS(4)
  2173.  IF rez<>0
  2174.   alrt$=''NEOLOAD only works in|Low Resolution.''
  2175.   ALERT 3,alrt$,1,''Exit'',b
  2176.   END
  2177.  ENDIF
  2178.  '
  2179. RETURN
  2180. '
  2181. PROCEDURE choose_pic
  2182.  '
  2183.  
  2184.  
  2185.      The next section was included to allow you to select a 
  2186. NEOchrome-format file using the standard GEM file selector. If 
  2187. you'd like to load a predetermined file, omit this procedure and 
  2188. define Filename$ as the name of the desired program before calling 
  2189. Procedure Load_colour.
  2190.  
  2191.  
  2192.  '
  2193.  disk$=''*.NEO''
  2194.  FILESELECT disk$,'''',filename$
  2195.  IF filename$=''''
  2196.   END
  2197.  ENDIF
  2198.  '
  2199. RETURN
  2200. '
  2201. PROCEDURE load_colour
  2202.  '
  2203.  OPEN ''I'',#1,filename$
  2204.  temp$=INPUT$(38,#1)
  2205.  
  2206.  
  2207.  
  2208. The first six bytes of the file don't matter,  so we'll strip them 
  2209. off.
  2210.  
  2211.  
  2212.  colour$=MID$(temp$,7,32)
  2213.  CLOSE #1
  2214.  '
  2215.  
  2216.  
  2217. Next, we'll break down the two-byte color values into values which 
  2218. we can assign to our alternate palette, and install the colors.
  2219.  
  2220.  
  2221.  palnum=0
  2222.  count=0
  2223.  REPEAT
  2224.   hibyte=ASC(MID$(colour$,count,1))
  2225.   INC count
  2226.   lobyte=ASC(MID$(colour$,count,1))
  2227.   INC count
  2228.   pal2(palnum)=(hibyte*256)+lobyte
  2229.   INC palnum
  2230.  UNTIL palnum=15
  2231.  '
  2232. RETURN
  2233. '
  2234.  
  2235. The  following XBIOS routine changes the hardware pointer  to  the 
  2236. palette  to point to the variable Colour$.  Changing this  pointer 
  2237. installs the new palette.
  2238.  
  2239.  
  2240.  
  2241. PROCEDURE install_colour
  2242.  '
  2243.  VOID XBIOS(6,L:VARPTR(colour$))
  2244.  '
  2245. RETURN
  2246. '
  2247.  
  2248.  
  2249.   Here's a little trick for loading the picture. XBIOS (2) is an 
  2250. XBIOS function which returns the location of the physical screen. 
  2251. This will vary for 520s and 1040s. Actually, we're cheating a bit 
  2252. here. We know that the first 128 bytes of a NEOchrome file contain 
  2253. information we're not interested in (information concerning the 
  2254. resolution, which is never used, the color palette, and the color 
  2255. rotation ). What we'll do is ignore this information and begin 
  2256. loading the picture into an absolute memory location 128 bytes 
  2257. lower than the beginning of screen memory. This area isn't usually 
  2258. used for anything, and provides an easy way to strip off the 
  2259. unneeded bytes and load the picture image.
  2260.  
  2261.  
  2262. PROCEDURE show_pic
  2263.  '
  2264.  physbase=XBIOS(2)
  2265.  BLOAD filename$,physbase-128
  2266.  '
  2267. RETURN
  2268. '
  2269. ' Save Original Color Palette
  2270. '
  2271. PROCEDURE save_palette
  2272.  '
  2273.  FOR i=0 TO 15
  2274.   palette(i)=XBIOS(7,W:i,W:-1)
  2275.  NEXT i
  2276.  '
  2277. RETURN
  2278. '
  2279. PROCEDURE restore_palette
  2280.  '
  2281.  FOR i=0 TO 15
  2282.   SETCOLOR i,palette(i)
  2283.  NEXT i
  2284.  '
  2285. RETURN
  2286.  
  2287.  
  2288.  
  2289. Great Graphics
  2290.  
  2291.      As you have seen from these simple examples, GFA BASIC makes 
  2292. graphics programming easy. It's not necessary to resort to PEEK's 
  2293. and POKE's to achieve the spectacular. This is only the starting 
  2294. point. As you continue to explore graphics with GFA BASIC, you'll 
  2295. be amazed at the power you can unleash as use the power of the 
  2296. 68000 Microprocessor.
  2297.    In the next chapter, we'll introduce you to an even more 
  2298. impressive use of graphics -- Animation. Soon you'll be writing 
  2299. the games you dream about.
  2300.  
  2301. ⇦e you to  an  even  more 
  2302. impressive  use of graphics -- Ani
  2303.